#pragma once
#ifndef _KLAS_RENDERING_CORE_HPP_
#define _KLAS_RENDERING_CORE_HPP_

#include "../Library.hpp"
#include "../Platform.hpp"
#include "../math/Rectangle.hpp"
#include "../graphics/Font.hpp"
#include "../graphics/Texture.hpp"
#include "../graphics/ColoredVector2.hpp"
#include "../graphics/Transformation.hpp"
#include "../graphics/PrimitiveTypes.hpp"

#include <vector>
using std::vector;

namespace klas
{
  namespace graphics
  {  

    //! A base class that allows generic rendering.  All verticies pass through the rendering core.  The class is considered internal.
    /*! A laying system should be implemented, and works as follows.  Layer 1 renders, then 2, then 3... until ~65,000.  After that, layer 0 renders.
        If render(cam, layer) is called with layer being non-zero, then the specified layer is rendered, otherwise, all layers are rendered. */
    class KLAS_API RenderingCore: public virtual library::Base
    {
    public:

      //! A dtor that doesn't do anything.
      virtual ~RenderingCore() {}

      //! Add some text to be rendered.
      /*! \param text The text to render.
          \param font The font to render the text with.
          \param col The color to render the text.
          \param m3 The matrix to use when rendering the text.
          \param layer The layer to render the text on. */
      virtual void add(string text, Font* font, const Color& col, const Transformation& transform, double transparency, uint16 layer = 0) = 0;

      //! Add a texture to be rendered.
      /*! \param tex The texture to render.
          \param m3 The matrix to use when rendering the texture.
          \param col The color to apply to the texture.
          \param layer The layer to render the texture on. */
      virtual void add(Texture* tex, const Transformation& transform, double transparency, const Color& col = colors::White, uint16 layer = 1) = 0;

      //! Add a set of verticies to be rendered.
      /*! \param type The type of primitive that will be rendered.
          \param m3 The matrix to use when rendering the polygon.
          \param col The color of the polygon.
          \param layer The layer to render the polygon upon. */
      virtual void add(primitiveTypes::sPrimitiveType type, const Transformation& transform, const Color& col, double transparency, uint16 layer = 1) = 0;

      //! Render the screen.
      /*! \param cam The location of the screen, or what should be rendered.
          \param layer The layer to render.  Zero will render all layers. */
      virtual void render(const math::Rectd& cam, uint16 layer = 0) = 0;

      //! Removes objects added to the rendering core.
      /*! \param removeText If this bool is set to false, then text will not be removed. */
      virtual void clearCache(bool removeText = true) = 0;


    protected:

      //! Represents text to render.
      struct internalText
      {
        Transformation transform;
        string text;
        Font* font;
        uint16 layer;
        Color col;
        double transparency;
      };

      //! Represents a texture that needs to be rendered.
      struct internalTexture
      {
        Transformation transform;
        Texture* tex;
        uint16 layer;
        Color col;
        double transparency;
      };

      //! Represents a polygon that needs to be rendered.
      struct internalPrimitive
      {
        Transformation transform;
        Color col;
        primitiveTypes::sPrimitiveType type;
        uint16 layer;
        double transparency;
      };

    };
  }
}

#endif